package main

import "fmt"

func main() {
	demo3()
}

func demo1() {
	var array [10]int
	var slice = array[5:6] // 容量5-10
	/**
	lenth of slice:  1
	capacity of slice:  5
	true
	*/
	fmt.Println("lenth of slice: ", len(slice))
	fmt.Println("capacity of slice: ", cap(slice))
	fmt.Println(&slice[0] == &array[5])
}
func demo2() {
	// append函数执行时会判断切片容量是否能够存放新增元素，如果不能，则会重新申请存储空间，新存储空间将是原来的2倍或1.25倍（取决于扩展原空间大小），
	// 本例中实际执行了两次append操作，第一次空间增长到4，所以第二次append不会再扩容，所以新旧两个切片将共用一块存储空间。程序会输出”true”。
	var slice []int
	slice = append(slice, 1, 2, 3)
	newSlice := AddElement(slice, 4)
	fmt.Println(&slice[0] == &newSlice[0]) // true
}

func AddElement(slice []int, e int) []int {
	return append(slice, e)
}

func demo3() {
	// order[low:high:max]操作意思是对order进行切片，新切片范围是[low, high),新切片容量是max。order长度为2倍的orderLen，
	// pollorder切片指的是order的前半部分切片，lockorder指的是order的后半部分切片，即原order分成了两段。
	// 所以，pollorder和lockerorder的长度和容量都是orderLen，即5。
	orderLen := 5
	order := make([]uint16, 2*orderLen)
	pollorder := order[:orderLen:orderLen]
	lockorder := order[orderLen:][:orderLen:orderLen]
	fmt.Println("len(pollorder) = ", len(pollorder)) // 5
	fmt.Println("cap(pollorder) = ", cap(pollorder)) // 5
	fmt.Println("len(lockorder) = ", len(lockorder)) // 5
	fmt.Println("cap(lockorder) = ", cap(lockorder)) // 5
}

func demo4() {
	// 切片追加, make初始化均为0
	s := make([]int, 10)
	s = append(s, 1, 2, 3)
	fmt.Println(s) // [0 0 0 0 0 0 0 0 0 0 1 2 3]
}

func demo5() {
	s1 := []int{1, 2, 3}
	s2 := []int{4, 5}
	s1 = append(s1, s2...) //  两个slice在append的时候，记住需要进行将第二个slice进行...打散再拼接。
	fmt.Println(s1)

	// 切片指针的解引用。
	// 可以使用list:=make([]int,0) list类型为切片
	// 或使用*list = append(*list, 1) list类型为指针
	list := new([]int)
	//list = append(list, 1) // 编译错误
	fmt.Println(list)
	/**
	new和make的区别：
		二者都是内存的分配（堆上），但是make只用于slice、map以及channel的初始化（非零值）；而new用于类型的内存分配，并且内存置为零。
		所以在我们编写程序的时候，就可以根据自己的需要很好的选择了。
		make返回的还是这三个引用类型本身；而new返回的是指向类型的指针。
	*/
}
